﻿using System.IO;

namespace Kise.LprCapturer
{
    public static class Helper
    {
        public static bool IsH264Header(byte[] buffer)
        {
            return (buffer[0] == 0x0) &&
                   (buffer[1] == 0x0) &&
                   (buffer[2] == 0x0) &&
                   (buffer[3] == 0x01) &&
                   (buffer[4] == 0x67);
        }

        public static string GeneratePath(string format, string directory, LprCaptured lprCaptured, int idx)
        {
            //{0}：年 {1}：月 {2}：日 {3}：时 {4}：分 {5}：秒 {6}：毫秒
            //{7}：设备编号 {8}：车道
            //{9}：号牌号码 {10}：号牌颜色 {11}：车速 {12}：违法类型 {13}：图片编号

            var fileName = string.Format(format,
                lprCaptured.CaptureTime.Year, lprCaptured.CaptureTime.Month, lprCaptured.CaptureTime.Day, lprCaptured.CaptureTime.Hour, lprCaptured.CaptureTime.Minute, lprCaptured.CaptureTime.Second, lprCaptured.CaptureTime.Millisecond,
                lprCaptured.LocationId, lprCaptured.RoadNo,
                lprCaptured.LprNumber, Wenton2LisidaColorConverter.Convert(lprCaptured.LprColorCode), lprCaptured.Speed.HasValue ? lprCaptured.Speed : 0, lprCaptured.ViolationCode, idx);
            return Path.Combine(directory, fileName + ".jpg");
        }

        //从YUV数据重建出R(Red)
        static byte GetYUVR(int nY, int nU, int nV)
        {
            int nR;    //V=nV-128
            nR = nY + (nV - 128) + ((nV - 128) * 103 >> 8);// v + ((v * 103) >> 8);

            //溢出检测
            if (nR > 255)
                nR = 255;
            if (nR < 0)
                nR = 0;
            return (byte)nR;
        }

        //从YUV数据重建出G(Green)
        static byte GetYUVG(int nY, int nU, int nV)
        {
            int nG;    //U = nU-128
            nG = nY - (((nU - 128) * 88 >> 8) + ((nV - 128) * 183 >> 8));//((u * 88) >> 8) +((v * 183) >> 8);

            //溢出检测
            if (nG > 255)
                nG = 255;
            if (nG < 0)
                nG = 0;
            return (byte)nG;
        }
        //从YUV数据重建出B(Blue)
        static byte GetYUVB(int nY, int nU, int nV)
        {
            int nB;
            nB = nY + (nU - 128) + ((nU - 128) * 198 >> 8);//u +( (u*198) >> 8);

            //溢出检测
            if (nB > 255)
                nB = 255;
            if (nB < 0)
                nB = 0;
            return (byte)nB;
        }
        /**************************************************************************
        函数名称: YUV422_TO_RGB
        函数功能: 转换YUV422数据为RGB数据
        函数参数: BYTE* pYUV -- 指向输入的YUV422数据
                  BYTE* pRGB -- 指向输出的RGB数据
                  int width  -- 图像宽度
                  int height -- 高度
        返 回 值: int -- 如果传入的数据指针为NULL 返回-1 如果传入的长宽参数不正确 返回-2
                         转换成功返回0
        **************************************************************************/
        public static unsafe bool YUV422_TO_RGB(byte* pYUV, byte* pRGB, int width, int height)
        {
            //参数检测
            if (pYUV == null) return false;
            if (pRGB == null) return false;
            if ((width <= 0) || (width >= 5000)) return false;
            if ((height <= 0) || (height >= 5000)) return false;


            int i = 0;
            int j = 0;
            for (i = 0; i < height; i++)
            {
                for (j = 0; j < width * 2; j += 4)
                {
                    int y1, u, y2, v;
                    byte r, g, b;
                    u = pYUV[i * width * 2 + j + 0];
                    y1 = pYUV[i * width * 2 + j + 1];
                    v = pYUV[i * width * 2 + j + 2];
                    y2 = pYUV[i * width * 2 + j + 3];

                    r = GetYUVR(y1, u, v);
                    g = GetYUVG(y1, u, v);
                    b = GetYUVB(y1, u, v);

                    *pRGB++ = b; // first pixel
                    *pRGB++ = g; // first pixel
                    *pRGB++ = r; // first pixel

                    r = GetYUVR(y2, u, v);
                    g = GetYUVG(y2, u, v);
                    b = GetYUVB(y2, u, v);

                    *pRGB++ = b; // second pixel
                    *pRGB++ = g; // second pixel
                    *pRGB++ = r; // second pixel
                }
            }
            return true;
        }

        public static int ReadLength(byte[] buffer, int offset, int size, Stream stream)
        {
            var count = 0;
            var bytesLeftToRead = size - count;
            while (bytesLeftToRead > 0)
            {
                var bytesRead = stream.Read(buffer, offset + count, bytesLeftToRead);
                count += bytesRead;
                if (bytesRead == 0)
                {
                    break;
                }

                bytesLeftToRead -= bytesRead;
            }

            return count;
        }

    }
}
